// 2010年版权归Go作者所有。版权所有。
// 此源代码的使用受BSD样式的约束
// 可以在许可证文件中找到的许可证。

package fmt

import (
	"errors"
	"io"
	"math"
	"os"
	"reflect"
	"strconv"
	"sync"
	"unicode/utf8"
)

// ScanState表示传递给自定义扫描仪的扫描仪状态。
// 扫描仪可以一次扫描一个符文或询问扫描状态
// 查找下一个空格分隔的令牌。
type ScanState interface {
	// ReadRune从输入中读取下一个rune（Unicode代码点）。
	// 如果在Scanln、Fscanln或Sscanln期间调用，ReadRune（）将
	// 在返回第一个'\n'后或在读取之后返回EOF
	// 指定的宽度。
	ReadRune() (r rune, size int, err error)
	// UnreadRune导致下一次调用ReadRune返回相同的符文。
	UnreadRune() error
	// SkipSpace跳过输入中的空间。换行符被适当地处理
	// 用于正在执行的操作；请参阅软件包文档
	// 了解更多信息。
	SkipSpace()
	// 如果skipSpace为true，则令牌跳过输入中的空格，然后返回
	// 运行符合f（c）的Unicode代码点c。如果f为零，
	// !使用unicode.IsSpace（c）；也就是说，令牌将保留非空格
	// 人物。对于正在执行的操作，应适当处理换行符
	// 表演；有关更多信息，请参阅软件包文档。
	// 返回的切片指向可能被覆盖的共享数据
	// 下一次调用Token时，使用ScanState调用Scan函数
	// 作为输入，或者当调用Scan方法返回时。
	Token(skipSpace bool, f func(rune) bool) (token []byte, err error)
	// Width返回Width选项的值以及是否已设置该选项。
	// 单位为Unicode代码点。
	Width() (wid int, ok bool)
	// 因为ReadRune是由接口实现的，所以永远不应该执行Read
	// 由扫描例程和的有效实现调用
	// ScanState可以选择始终从读取返回错误。
	Read(buf []byte) (n int, err error)
}

// Scanner由任何具有扫描方法的值实现，该扫描方法
// 表示值的输入，并将结果存储在
// 接收器，它必须是一个有用的指针。调用Scan方法
// 用于Scan、Scanf或Scanln的任何参数。
type Scanner interface {
	Scan(state ScanState, verb rune) error
}

// 扫描扫描从标准输入读取的文本，存储连续的
// 空格将值分隔为连续参数。换行计数
// 作为空间。它返回成功扫描的项目数。
// 如果这少于参数数量，err将报告原因。
func Scan(a ...interface{}) (n int, err error) {
	return Fscan(os.Stdin, a...)
}

// Scanln与Scan类似，但在换行时停止扫描，然后
// 在最后一项之后必须有换行符或EOF。
func Scanln(a ...interface{}) (n int, err error) {
	return Fscanln(os.Stdin, a...)
}

// Scanf扫描从标准输入读取的文本，存储连续的
// 将值分隔为连续参数，由
// 格式。它返回成功扫描的项目数。
// 如果这少于参数数量，err将报告原因。
// 输入中的换行符必须与格式中的换行符匹配。
// 唯一的例外是：动词%c总是扫描文本中的下一个符文
// 输入，即使是空格（或制表符等）或换行符。
func Scanf(format string, a ...interface{}) (n int, err error) {
	return Fscanf(os.Stdin, format, a...)
}

type stringReader string

func (r *stringReader) Read(b []byte) (n int, err error) {
	n = copy(b, *r)
	*r = (*r)[n:]
	if n == 0 {
		err = io.EOF
	}
	return
}

// Sscan扫描参数字符串，存储分隔的连续空格
// 将值转换为连续参数。换行符算作空格。信息技术
// 返回成功扫描的项目数。如果是更少的话
// 如果参数的数量超过，err将报告原因。
func Sscan(str string, a ...interface{}) (n int, err error) {
	return Fscan((*stringReader)(&str), a...)
}

// Sscanln与Sscan类似，但在换行时停止扫描，然后
// 在最后一项之后必须有换行符或EOF。
func Sscanln(str string, a ...interface{}) (n int, err error) {
	return Fscanln((*stringReader)(&str), a...)
}

// Sscanf扫描参数字符串，存储分隔的连续空格
// 值转换为由格式确定的连续参数。信息技术
// 返回成功分析的项目数。
// 输入中的换行符必须与格式中的换行符匹配。
func Sscanf(str string, format string, a ...interface{}) (n int, err error) {
	return Fscanf((*stringReader)(&str), format, a...)
}

// Fscan扫描从r读取的文本，存储连续的分隔空间
// 将值转换为连续参数。换行符算作空格。信息技术
// 返回成功扫描的项目数。如果是更少的话
// 如果参数的数量超过，err将报告原因。
func Fscan(r io.Reader, a ...interface{}) (n int, err error) {
	s, old := newScanState(r, true, false)
	n, err = s.doScan(a)
	s.free(old)
	return
}

// Fscanln类似于Fscan，但会在换行时停止扫描，然后
// 在最后一项之后必须有换行符或EOF。
func Fscanln(r io.Reader, a ...interface{}) (n int, err error) {
	s, old := newScanState(r, false, true)
	n, err = s.doScan(a)
	s.free(old)
	return
}

// Fscanf扫描从r读取的文本，存储连续的分隔空间
// 值转换为由格式确定的连续参数。信息技术
// 返回成功分析的项目数。
// 输入中的换行符必须与格式中的换行符匹配。
func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) {
	s, old := newScanState(r, false, false)
	n, err = s.doScanf(format, a)
	s.free(old)
	return
}

// scanError表示扫描软件生成的错误。
// 它被用作唯一的签名，用于在恢复时识别此类错误。
type scanError struct {
	err error
}

const eof = -1

// ss是ScanState的内部实现。
type ss struct {
	rs    io.RuneScanner // 在哪里读取输入
	buf   buffer         // 令牌累加器
	count int            // 到目前为止，符文已经消耗殆尽。
	atEOF bool           // 已读取EOF
	ssave
}

// ssave包含ss中需要修改的部分
// 在递归扫描上保存和还原。
type ssave struct {
	validSave bool // 是或曾经是真实党卫军的一部分。
	nlIsEnd   bool // 换行符是否终止扫描
	nlIsSpace bool // 换行符是否算作空白
	argLimit  int  // 此参数的ss.count的最大值；argLimit<=限制
	limit     int  // ss.count的最大值。
	maxWid    int  // 此参数的宽度。
}

// Read方法仅处于ScanState中，因此ScanState
// 满足io.Reader。当它被用作
// 有意的，所以没有必要让它实际工作。
func (s *ss) Read(buf []byte) (n int, err error) {
	return 0, errors.New("ScanState's Read should not be called. Use ReadRune")
}

func (s *ss) ReadRune() (r rune, size int, err error) {
	if s.atEOF || s.count >= s.argLimit {
		err = io.EOF
		return
	}

	r, size, err = s.rs.ReadRune()
	if err == nil {
		s.count++
		if s.nlIsEnd && r == '\n' {
			s.atEOF = true
		}
	} else if err == io.EOF {
		s.atEOF = true
	}
	return
}

func (s *ss) Width() (wid int, ok bool) {
	if s.maxWid == hugeWid {
		return 0, false
	}
	return s.maxWid, true
}

// public方法返回一个错误；这个私人的恐慌。
// 如果getRune达到EOF，则返回值为EOF（-1）。
func (s *ss) getRune() (r rune) {
	r, _, err := s.ReadRune()
	if err != nil {
		if err == io.EOF {
			return eof
		}
		s.error(err)
	}
	return
}

// mustReadRune将io.EOF变为恐慌（io.ERRUNSEXPECTEDOF）。
// 在诸如字符串扫描之类的情况下调用它，其中EOF是
// 语法错误。
func (s *ss) mustReadRune() (r rune) {
	r = s.getRune()
	if r == eof {
		s.error(io.ErrUnexpectedEOF)
	}
	return
}

func (s *ss) UnreadRune() error {
	s.rs.UnreadRune()
	s.atEOF = false
	s.count--
	return nil
}

func (s *ss) error(err error) {
	panic(scanError{err})
}

func (s *ss) errorString(err string) {
	panic(scanError{errors.New(err)})
}

func (s *ss) Token(skipSpace bool, f func(rune) bool) (tok []byte, err error) {
	defer func() {
		if e := recover(); e != nil {
			if se, ok := e.(scanError); ok {
				err = se.err
			} else {
				panic(e)
			}
		}
	}()
	if f == nil {
		f = notSpace
	}
	s.buf = s.buf[:0]
	tok = s.token(skipSpace, f)
	return
}

// 空格是unicode.White_空格范围的副本，
// 避免依赖unicode包。
var space = [][2]uint16{
	{0x0009, 0x000d},
	{0x0020, 0x0020},
	{0x0085, 0x0085},
	{0x00a0, 0x00a0},
	{0x1680, 0x1680},
	{0x2000, 0x200a},
	{0x2028, 0x2029},
	{0x202f, 0x202f},
	{0x205f, 0x205f},
	{0x3000, 0x3000},
}

func isSpace(r rune) bool {
	if r >= 1<<16 {
		return false
	}
	rx := uint16(r)
	for _, rng := range space {
		if rx < rng[0] {
			return false
		}
		if rx <= rng[1] {
			return true
		}
	}
	return false
}

// notSpace是令牌中使用的默认扫描函数。
func notSpace(r rune) bool {
	return !isSpace(r)
}

// readRune是一种能够读取UTF-8编码代码点的结构
// 来自io阅读器。如果提供给扫描器的读卡器
// 尚未实现io.RuneScanner。
type readRune struct {
	reader   io.Reader
	buf      [utf8.UTFMax]byte // 仅在ReadRune中使用
	pending  int               // pendBuf中的字节数；对于坏的UTF-8，仅>0
	pendBuf  [utf8.UTFMax]byte // 剩余字节
	peekRune rune              // 如果>=0下一个符文；当<0是^（上一个符文）
}

// readByte返回输入的下一个字节，可能是
// 如果UTF-8格式不正确，则为先前读取的剩余内容。
func (r *readRune) readByte() (b byte, err error) {
	if r.pending > 0 {
		b = r.pendBuf[0]
		copy(r.pendBuf[0:], r.pendBuf[1:])
		r.pending--
		return
	}
	n, err := io.ReadFull(r.reader, r.pendBuf[:1])
	if n != 1 {
		return 0, err
	}
	return r.pendBuf[0], err
}

// ReadRune返回源代码的下一个UTF-8编码代码点
// io.r内的读卡器。
func (r *readRune) ReadRune() (rr rune, size int, err error) {
	if r.peekRune >= 0 {
		rr = r.peekRune
		r.peekRune = ^r.peekRune
		size = utf8.RuneLen(rr)
		return
	}
	r.buf[0], err = r.readByte()
	if err != nil {
		return
	}
	if r.buf[0] < utf8.RuneSelf { // 常见ASCII码的快速检查
		rr = rune(r.buf[0])
		size = 1 // 已知为1。
		// 翻转符文的各个部分，使其可供未读符文的人使用。
		r.peekRune = ^rr
		return
	}
	var n int
	for n = 1; !utf8.FullRune(r.buf[:n]); n++ {
		r.buf[n], err = r.readByte()
		if err != nil {
			if err == io.EOF {
				err = nil
				break
			}
			return
		}
	}
	rr, size = utf8.DecodeRune(r.buf[:n])
	if size < n { // 如果出现错误，请保存字节以便下次读取
		copy(r.pendBuf[r.pending:], r.buf[size:n])
		r.pending += n - size
	}
	// 翻转符文的各个部分，使其可供未读符文的人使用。
	r.peekRune = ^rr
	return
}

func (r *readRune) UnreadRune() error {
	if r.peekRune >= 0 {
		return errors.New("fmt: scanning called UnreadRune with no rune available")
	}
	// 反转先前读取的符文的位翻转以获得有效>=0状态。
	r.peekRune = ^r.peekRune
	return nil
}

var ssFree = sync.Pool{
	New: func() interface{} { return new(ss) },
}

// newScanState分配一个新的ss结构或获取一个缓存的结构。
func newScanState(r io.Reader, nlIsSpace, nlIsEnd bool) (s *ss, old ssave) {
	s = ssFree.Get().(*ss)
	if rs, ok := r.(io.RuneScanner); ok {
		s.rs = rs
	} else {
		s.rs = &readRune{reader: r, peekRune: -1}
	}
	s.nlIsSpace = nlIsSpace
	s.nlIsEnd = nlIsEnd
	s.atEOF = false
	s.limit = hugeWid
	s.argLimit = hugeWid
	s.maxWid = hugeWid
	s.validSave = true
	s.count = 0
	return
}

// free在ssFree中保存使用过的ss结构；避免每次调用都进行分配。
func (s *ss) free(old ssave) {
	// 如果它是递归使用的，只需恢复旧状态即可。
	if old.validSave {
		s.ssave = old
		return
	}
	// 不要保留具有大缓冲区的ss结构。
	if cap(s.buf) > 1024 {
		return
	}
	s.buf = s.buf[:0]
	s.rs = nil
	ssFree.Put(s)
}

// SkipSpace提供了扫描方法，可以跳过空格和换行
// 与格式字符串设置的当前扫描模式保持一致的字符
// 和扫描/扫描。
func (s *ss) SkipSpace() {
	for {
		r := s.getRune()
		if r == eof {
			return
		}
		if r == '\r' && s.peek("\n") {
			continue
		}
		if r == '\n' {
			if s.nlIsSpace {
				continue
			}
			s.errorString("unexpected newline")
			return
		}
		if !isSpace(r) {
			s.UnreadRune()
			break
		}
	}
}

// 令牌从输入返回下一个空格分隔的字符串。信息技术
// 跳过空白。对于Scanln，它在换行时停止。扫描时，
// 换行符被视为空格。
func (s *ss) token(skipSpace bool, f func(rune) bool) []byte {
	if skipSpace {
		s.SkipSpace()
	}
	// 读到空格或换行符
	for {
		r := s.getRune()
		if r == eof {
			break
		}
		if !f(r) {
			s.UnreadRune()
			break
		}
		s.buf.writeRune(r)
	}
	return s.buf
}

var complexError = errors.New("syntax error scanning complex number")
var boolError = errors.New("syntax error scanning boolean")

func indexRune(s string, r rune) int {
	for i, c := range s {
		if c == r {
			return i
		}
	}
	return -1
}

// consume读取输入中的下一个符文，并报告它是否在ok字符串中。
// 如果accept为true，则将字符放入输入标记中。
func (s *ss) consume(ok string, accept bool) bool {
	r := s.getRune()
	if r == eof {
		return false
	}
	if indexRune(ok, r) >= 0 {
		if accept {
			s.buf.writeRune(r)
		}
		return true
	}
	if r != eof && accept {
		s.UnreadRune()
	}
	return false
}

// peek报告下一个字符是否在ok字符串中，而不使用它。
func (s *ss) peek(ok string) bool {
	r := s.getRune()
	if r != eof {
		s.UnreadRune()
	}
	return indexRune(ok, r) >= 0
}

func (s *ss) notEOF() {
	// 确保有数据要读取。
	if r := s.getRune(); r == eof {
		panic(io.EOF)
	}
	s.UnreadRune()
}

// accept检查输入中的下一个符文。如果它是字符串中的一个字节（sic），它会将其放入
// 缓冲区，并返回true。否则返回false。
func (s *ss) accept(ok string) bool {
	return s.consume(ok, true)
}

// okVerb验证谓词是否存在于列表中，如果不存在，则适当设置s.err。
func (s *ss) okVerb(verb rune, okVerbs, typ string) bool {
	for _, v := range okVerbs {
		if v == verb {
			return true
		}
	}
	s.errorString("bad verb '%" + string(verb) + "' for " + typ)
	return false
}

// scanBool返回由下一个标记表示的布尔值。
func (s *ss) scanBool(verb rune) bool {
	s.SkipSpace()
	s.notEOF()
	if !s.okVerb(verb, "tv", "boolean") {
		return false
	}
	// 对布尔值进行语法检查很烦人。我们对这个案子并不挑剔。
	switch s.getRune() {
	case '0':
		return false
	case '1':
		return true
	case 't', 'T':
		if s.accept("rR") && (!s.accept("uU") || !s.accept("eE")) {
			s.error(boolError)
		}
		return true
	case 'f', 'F':
		if s.accept("aA") && (!s.accept("lL") || !s.accept("sS") || !s.accept("eE")) {
			s.error(boolError)
		}
		return false
	}
	return false
}

// 数值元素
const (
	binaryDigits      = "01"
	octalDigits       = "01234567"
	decimalDigits     = "0123456789"
	hexadecimalDigits = "0123456789aAbBcCdDeEfF"
	sign              = "+-"
	period            = "."
	exponent          = "eEpP"
)

// getBase返回由谓词及其数字字符串表示的数字基。
func (s *ss) getBase(verb rune) (base int, digits string) {
	s.okVerb(verb, "bdoUxXv", "integer") // 设置s.err
	base = 10
	digits = decimalDigits
	switch verb {
	case 'b':
		base = 2
		digits = binaryDigits
	case 'o':
		base = 8
		digits = octalDigits
	case 'x', 'X', 'U':
		base = 16
		digits = hexadecimalDigits
	}
	return
}

// scanNumber返回从此处开始的具有指定数字的数字字符串。
func (s *ss) scanNumber(digits string, haveDigits bool) string {
	if !haveDigits {
		s.notEOF()
		if !s.accept(digits) {
			s.errorString("expected integer")
		}
	}
	for s.accept(digits) {
	}
	return string(s.buf)
}

// scanRune返回输入中的下一个rune值。
func (s *ss) scanRune(bitSize int) int64 {
	s.notEOF()
	r := s.getRune()
	n := uint(bitSize)
	x := (int64(r) << (64 - n)) >> (64 - n)
	if x != int64(r) {
		s.errorString("overflow on character value " + string(r))
	}
	return int64(r)
}

// scanBasePrefix报告整数是否以基前缀开头
// 并返回基数、数字字符串以及是否找到零。
// 仅当动词为%v时才调用它。
func (s *ss) scanBasePrefix() (base int, digits string, zeroFound bool) {
	if !s.peek("0") {
		return 0, decimalDigits + "_", false
	}
	s.accept("0")
	// 0、0b、0o、0x的特殊情况。
	switch {
	case s.peek("bB"):
		s.consume("bB", true)
		return 0, binaryDigits + "_", true
	case s.peek("oO"):
		s.consume("oO", true)
		return 0, octalDigits + "_", true
	case s.peek("xX"):
		s.consume("xX", true)
		return 0, hexadecimalDigits + "_", true
	default:
		return 0, octalDigits + "_", true
	}
}

// scanInt返回由下一个
// 令牌，正在检查溢出。任何错误都存储在s.err中。
func (s *ss) scanInt(verb rune, bitSize int) int64 {
	if verb == 'c' {
		return s.scanRune(bitSize)
	}
	s.SkipSpace()
	s.notEOF()
	base, digits := s.getBase(verb)
	haveDigits := false
	if verb == 'U' {
		if !s.consume("U", false) || !s.consume("+", false) {
			s.errorString("bad unicode format ")
		}
	} else {
		s.accept(sign) // 如果有符号，它将留在令牌缓冲区中。
		if verb == 'v' {
			base, digits, haveDigits = s.scanBasePrefix()
		}
	}
	tok := s.scanNumber(digits, haveDigits)
	i, err := strconv.ParseInt(tok, base, 64)
	if err != nil {
		s.error(err)
	}
	n := uint(bitSize)
	x := (i << (64 - n)) >> (64 - n)
	if x != i {
		s.errorString("integer overflow on token " + tok)
	}
	return i
}

// scanUint返回表示的无符号整数的值
// 通过下一个标记，检查溢出。任何错误都存储在s.err中。
func (s *ss) scanUint(verb rune, bitSize int) uint64 {
	if verb == 'c' {
		return uint64(s.scanRune(bitSize))
	}
	s.SkipSpace()
	s.notEOF()
	base, digits := s.getBase(verb)
	haveDigits := false
	if verb == 'U' {
		if !s.consume("U", false) || !s.consume("+", false) {
			s.errorString("bad unicode format ")
		}
	} else if verb == 'v' {
		base, digits, haveDigits = s.scanBasePrefix()
	}
	tok := s.scanNumber(digits, haveDigits)
	i, err := strconv.ParseUint(tok, base, 64)
	if err != nil {
		s.error(err)
	}
	n := uint(bitSize)
	x := (i << (64 - n)) >> (64 - n)
	if x != i {
		s.errorString("unsigned integer overflow on token " + tok)
	}
	return i
}

// floatToken返回从这里开始的浮点数，长度不超过swid
// 如果指定了宽度。它的语法并不严格，因为它不检查语法
// 我们至少有一些数字，但Atof会这样做。
func (s *ss) floatToken() string {
	s.buf = s.buf[:0]
	// 南？
	if s.accept("nN") && s.accept("aA") && s.accept("nN") {
		return string(s.buf)
	}
	// 领先标志？
	s.accept(sign)
	// Inf？
	if s.accept("iI") && s.accept("nN") && s.accept("fF") {
		return string(s.buf)
	}
	digits := decimalDigits + "_"
	exp := exponent
	if s.accept("0") && s.accept("xX") {
		digits = hexadecimalDigits + "_"
		exp = "pP"
	}
	// 数字？
	for s.accept(digits) {
	}
	// 小数点？
	if s.accept(period) {
		// 小部分
		for s.accept(digits) {
		}
	}
	// 拥护者
	if s.accept(exp) {
		// 领先标志？
		s.accept(sign)
		// 数字？
		for s.accept(decimalDigits + "_") {
		}
	}
	return string(s.buf)
}

// complexTokens返回从这里开始的复数的实部和虚部。
// 数字可以用括号括起来，格式为（N+Ni），其中N是浮点
// 编号，并且其中没有空格。
func (s *ss) complexTokens() (real, imag string) {
	// TODO:独立接受N和Ni？
	parens := s.accept("(")
	real = s.floatToken()
	s.buf = s.buf[:0]
	// 现在必须有一个标志。
	if !s.accept("+-") {
		s.error(complexError)
	}
	// 符号现在处于缓冲区中
	imagSign := string(s.buf)
	imag = s.floatToken()
	if !s.accept("i") {
		s.error(complexError)
	}
	if parens && !s.accept(")") {
		s.error(complexError)
	}
	return real, imagSign + imag
}

func hasX(s string) bool {
	for i := 0; i < len(s); i++ {
		if s[i] == 'x' || s[i] == 'X' {
			return true
		}
	}
	return false
}

// convertFloat将字符串转换为浮点值。
func (s *ss) convertFloat(str string, n int) float64 {
	// strconv.ParseFloat将处理“+0x1.fp+2”，
	// 但我们必须实施我们的非标准政策
	// 十进制+二进制指数混合（1.2p4）。
	if p := indexRune(str, 'p'); p >= 0 && !hasX(str) {
		// Atof不处理二次幂指数，
		// 但它们很容易评估。
		f, err := strconv.ParseFloat(str[:p], n)
		if err != nil {
			// 将整个字符串放入错误。
			if e, ok := err.(*strconv.NumError); ok {
				e.Num = str
			}
			s.error(err)
		}
		m, err := strconv.Atoi(str[p+1:])
		if err != nil {
			// 将整个字符串放入错误。
			if e, ok := err.(*strconv.NumError); ok {
				e.Num = str
			}
			s.error(err)
		}
		return math.Ldexp(f, m)
	}
	f, err := strconv.ParseFloat(str, n)
	if err != nil {
		s.error(err)
	}
	return f
}

// convertComplex将下一个标记转换为complex128值。
// atof参数是基础类型的特定于类型的读取器。
// 如果我们正在阅读complex64，atof将解析float32并转换它们
// 以避免为每个复杂类型复制此代码。
func (s *ss) scanComplex(verb rune, n int) complex128 {
	if !s.okVerb(verb, floatVerbs, "complex") {
		return 0
	}
	s.SkipSpace()
	s.notEOF()
	sreal, simag := s.complexTokens()
	real := s.convertFloat(sreal, n/2)
	imag := s.convertFloat(simag, n/2)
	return complex(real, imag)
}

// convertString返回由下一个输入字符表示的字符串。
// 输入的格式由动词决定。
func (s *ss) convertString(verb rune) (str string) {
	if !s.okVerb(verb, "svqxX", "string") {
		return ""
	}
	s.SkipSpace()
	s.notEOF()
	switch verb {
	case 'q':
		str = s.quotedString()
	case 'x', 'X':
		str = s.hexString()
	default:
		str = string(s.token(true, notSpace)) // %s和%v只返回下一个单词
	}
	return
}

// quotedString返回由下一个输入字符表示的双引号或反引号字符串。
func (s *ss) quotedString() string {
	s.notEOF()
	quote := s.getRune()
	switch quote {
	case '`':
		// 反向报价：任何东西都要等到EOF或反向报价。
		for {
			r := s.mustReadRune()
			if r == quote {
				break
			}
			s.buf.writeRune(r)
		}
		return string(s.buf)
	case '"':
		// 双引号：包括引号，并让strconv.Unquote执行反斜杠转义。
		s.buf.writeByte('"')
		for {
			r := s.mustReadRune()
			s.buf.writeRune(r)
			if r == '\\' {
				// 在合法的反斜杠转义中，无论多长时间，只有字符
				// 转义之后可以立即使用反斜杠或引号。
				// 因此，我们只需要保护反斜杠后的第一个字符。
				s.buf.writeRune(s.mustReadRune())
			} else if r == '"' {
				break
			}
		}
		result, err := strconv.Unquote(string(s.buf))
		if err != nil {
			s.error(err)
		}
		return result
	default:
		s.errorString("expected quoted string")
	}
	return ""
}

// 十六进制数字返回十六进制数字的值。
func hexDigit(d rune) (int, bool) {
	digit := int(d)
	switch digit {
	case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
		return digit - '0', true
	case 'a', 'b', 'c', 'd', 'e', 'f':
		return 10 + digit - 'a', true
	case 'A', 'B', 'C', 'D', 'E', 'F':
		return 10 + digit - 'A', true
	}
	return -1, false
}

// hexByte从输入返回下一个十六进制编码（两个字符）字节。
// 如果输入中的下一个字节未编码十六进制字节，则返回ok==false。
// 如果第一个字节为十六进制，第二个字节为非十六进制，则处理停止。
func (s *ss) hexByte() (b byte, ok bool) {
	rune1 := s.getRune()
	if rune1 == eof {
		return
	}
	value1, ok := hexDigit(rune1)
	if !ok {
		s.UnreadRune()
		return
	}
	value2, ok := hexDigit(s.mustReadRune())
	if !ok {
		s.errorString("illegal hex digit")
		return
	}
	return byte(value1<<4 | value2), true
}

// hexString返回以空格分隔的hexpair编码字符串。
func (s *ss) hexString() string {
	s.notEOF()
	for {
		b, ok := s.hexByte()
		if !ok {
			break
		}
		s.buf.writeByte(b)
	}
	if len(s.buf) == 0 {
		s.errorString("no hex data for %x string")
		return ""
	}
	return string(s.buf)
}

const (
	floatVerbs = "beEfFgGv"

	hugeWid = 1 << 30

	intBits     = 32 << (^uint(0) >> 63)
	uintptrBits = 32 << (^uintptr(0) >> 63)
)

// scanPercent扫描文字百分比字符。
func (s *ss) scanPercent() {
	s.SkipSpace()
	s.notEOF()
	if !s.accept("%") {
		s.errorString("missing literal %")
	}
}

// scanOne扫描单个值，从参数类型派生扫描程序。
func (s *ss) scanOne(verb rune, arg interface{}) {
	s.buf = s.buf[:0]
	var err error
	// 如果参数有自己的扫描方法，请使用该方法。
	if v, ok := arg.(Scanner); ok {
		err = v.Scan(s, verb)
		if err != nil {
			if err == io.EOF {
				err = io.ErrUnexpectedEOF
			}
			s.error(err)
		}
		return
	}

	switch v := arg.(type) {
	case *bool:
		*v = s.scanBool(verb)
	case *complex64:
		*v = complex64(s.scanComplex(verb, 64))
	case *complex128:
		*v = s.scanComplex(verb, 128)
	case *int:
		*v = int(s.scanInt(verb, intBits))
	case *int8:
		*v = int8(s.scanInt(verb, 8))
	case *int16:
		*v = int16(s.scanInt(verb, 16))
	case *int32:
		*v = int32(s.scanInt(verb, 32))
	case *int64:
		*v = s.scanInt(verb, 64)
	case *uint:
		*v = uint(s.scanUint(verb, intBits))
	case *uint8:
		*v = uint8(s.scanUint(verb, 8))
	case *uint16:
		*v = uint16(s.scanUint(verb, 16))
	case *uint32:
		*v = uint32(s.scanUint(verb, 32))
	case *uint64:
		*v = s.scanUint(verb, 64)
	case *uintptr:
		*v = uintptr(s.scanUint(verb, uintptrBits))
	// 浮动比较棘手，因为您希望扫描结果的精度，而不是
	// 高精度扫描并转换，以保持正确的错误状态。
	case *float32:
		if s.okVerb(verb, floatVerbs, "float32") {
			s.SkipSpace()
			s.notEOF()
			*v = float32(s.convertFloat(s.floatToken(), 32))
		}
	case *float64:
		if s.okVerb(verb, floatVerbs, "float64") {
			s.SkipSpace()
			s.notEOF()
			*v = s.convertFloat(s.floatToken(), 64)
		}
	case *string:
		*v = s.convertString(verb)
	case *[]byte:
		// 我们扫描到字符串并进行转换，以获得数据的副本。
		// 如果我们扫描到字节，切片将指向缓冲区。
		*v = []byte(s.convertString(verb))
	default:
		val := reflect.ValueOf(v)
		ptr := val
		if ptr.Kind() != reflect.Ptr {
			s.errorString("type not a pointer: " + val.Type().String())
			return
		}
		switch v := ptr.Elem(); v.Kind() {
		case reflect.Bool:
			v.SetBool(s.scanBool(verb))
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			v.SetInt(s.scanInt(verb, v.Type().Bits()))
		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
			v.SetUint(s.scanUint(verb, v.Type().Bits()))
		case reflect.String:
			v.SetString(s.convertString(verb))
		case reflect.Slice:
			// 目前，只能处理（重命名）[]字节。
			typ := v.Type()
			if typ.Elem().Kind() != reflect.Uint8 {
				s.errorString("can't scan type: " + val.Type().String())
			}
			str := s.convertString(verb)
			v.Set(reflect.MakeSlice(typ, len(str), len(str)))
			for i := 0; i < len(str); i++ {
				v.Index(i).SetUint(uint64(str[i]))
			}
		case reflect.Float32, reflect.Float64:
			s.SkipSpace()
			s.notEOF()
			v.SetFloat(s.convertFloat(s.floatToken(), v.Type().Bits()))
		case reflect.Complex64, reflect.Complex128:
			v.SetComplex(s.scanComplex(verb, v.Type().Bits()))
		default:
			s.errorString("can't scan type: " + val.Type().String())
		}
	}
}

// errorHandler将本地恐慌转化为错误返回。
func errorHandler(errp *error) {
	if e := recover(); e != nil {
		if se, ok := e.(scanError); ok { // 捕获本地错误
			*errp = se.err
		} else if eof, ok := e.(error); ok && eof == io.EOF { // 输入不足
			*errp = eof
		} else {
			panic(e)
		}
	}
}

// doScan在没有格式字符串的情况下完成真正的扫描工作。
func (s *ss) doScan(a []interface{}) (numProcessed int, err error) {
	defer errorHandler(&err)
	for _, arg := range a {
		s.scanOne('v', arg)
		numProcessed++
	}
	// 如果需要，检查换行符（或EOF）（Scanln等）。
	if s.nlIsEnd {
		for {
			r := s.getRune()
			if r == '\n' || r == eof {
				break
			}
			if !isSpace(r) {
				s.errorString("expected newline")
				break
			}
		}
	}
	return
}

// advance确定输入中的下一个字符是否匹配
// 格式的那些。它返回消耗的字节数（sic）
// 在格式中。输入或输出中所有空格字符的运行
// 格式表现为单个空格。不过，换行符很特殊：
// 格式中的换行符必须与输入中的换行符匹配，反之亦然。
// 此例程还处理%%case。如果返回值为零，
// 任何一种格式都以一个%（无后续%）或输入开头
// 是空的。如果为负，则表示输入与字符串不匹配。
func (s *ss) advance(format string) (i int) {
	for i < len(format) {
		fmtc, w := utf8.DecodeRuneInString(format[i:])

		// 空间处理。
		// 在本注释的其余部分，“空格”是指换行以外的空格。
		// 格式中的换行符匹配零个或多个空格的输入，然后匹配换行符或输入结尾。
		// 换行符之前格式的空格将收拢到换行符中。
		// 换行符后格式中的空格与相应输入换行符后的零个或多个空格匹配。
		// 格式中的其他空格与一个或多个空格的输入或输入结尾匹配。
		if isSpace(fmtc) {
			newlines := 0
			trailingSpace := false
			for isSpace(fmtc) && i < len(format) {
				if fmtc == '\n' {
					newlines++
					trailingSpace = false
				} else {
					trailingSpace = true
				}
				i += w
				fmtc, w = utf8.DecodeRuneInString(format[i:])
			}
			for j := 0; j < newlines; j++ {
				inputc := s.getRune()
				for isSpace(inputc) && inputc != '\n' {
					inputc = s.getRune()
				}
				if inputc != '\n' && inputc != eof {
					s.errorString("newline in format does not match input")
				}
			}
			if trailingSpace {
				inputc := s.getRune()
				if newlines == 0 {
					// 如果尾随空间单独存在（不跟随换行符），
					// 它必须至少找到一个空间来使用。
					if !isSpace(inputc) && inputc != eof {
						s.errorString("expected space in input to match format")
					}
					if inputc == '\n' {
						s.errorString("newline in input does not match format")
					}
				}
				for isSpace(inputc) && inputc != '\n' {
					inputc = s.getRune()
				}
				if inputc != eof {
					s.UnreadRune()
				}
			}
			continue
		}

		// 动词。
		if fmtc == '%' {
			// %字符串末尾有一个错误。
			if i+w == len(format) {
				s.errorString("missing verb: % at end of format string")
			}
			// %%就像一个真实的百分比
			nextc, _ := utf8.DecodeRuneInString(format[i+w:]) // 如果字符串为空，则将不匹配%
			if nextc != '%' {
				return
			}
			i += w // 跳过第一个%
		}

		// 文字。
		inputc := s.mustReadRune()
		if fmtc != inputc {
			s.UnreadRune()
			return -1
		}
		i += w
	}
	return
}

// 当使用格式字符串进行扫描时，doScanf将完成真正的工作。
// 目前，它只处理指向基本类型的指针。
func (s *ss) doScanf(format string, a []interface{}) (numProcessed int, err error) {
	defer errorHandler(&err)
	end := len(format) - 1
	// 我们对每个非平凡格式处理一项
	for i := 0; i <= end; {
		w := s.advance(format[i:])
		if w > 0 {
			i += w
			continue
		}
		// 要么我们无法前进，要么我们有一个百分比字符，要么我们的输入用完了。
		if format[i] != '%' {
			// 无法推进格式。为什么不呢？
			if w < 0 {
				s.errorString("input does not match format")
			}
			// 否则在EOF；下面处理的“操作数太多”错误
			break
		}
		i++ // %是一个字节

		// 我们有20（宽）吗？
		var widPresent bool
		s.maxWid, widPresent, i = parsenum(format, i, end)
		if !widPresent {
			s.maxWid = hugeWid
		}

		c, w := utf8.DecodeRuneInString(format[i:])
		i += w

		if c != 'c' {
			s.SkipSpace()
		}
		if c == '%' {
			s.scanPercent()
			continue // 不要使用参数。
		}
		s.argLimit = s.limit
		if f := s.count + s.maxWid; f < s.argLimit {
			s.argLimit = f
		}

		if numProcessed >= len(a) { // 操作数不足
			s.errorString("too few operands for format '%" + format[i-w:] + "'")
			break
		}
		arg := a[numProcessed]

		s.scanOne(c, arg)
		numProcessed++
		s.argLimit = s.limit
	}
	if numProcessed < len(a) {
		s.errorString("too many operands")
	}
	return
}
